/*
File Name: txproc.h
Description: Prototype description of Tx Processing
*/
#ifndef TXPROC_H
#define TXPROC_H
#ifdef __cplusplus
extern "C"
{
#endif ///__cplusplus
#include "macrodef.h"
#include "ndisdef.h"

#pragma pack(1)
/** \struct WCB 
 * WCB descriptor
*/
typedef struct _WCB 
{
//ULONG CheckBgn;
    ULONG Status;                   /** < Current Tx packet transmit status */
    ULONG TxControl;                /** < b16-17: Bus Aggregation Packet number 0~3 */
    
    struct {
        USHORT PktPtr;
        USHORT NextWCBPtr;      // Next WCB Offset
    };


    USHORT PktLen;                  /** < Tx packet length */
    UCHAR DestMACAdrHi[2];          /** < First 2 byte of destination MAC address */
    UCHAR DestMACAdrLow[4];         /** < Last 4 byte of destination MAC address */
    UCHAR Priority;
    UCHAR PowerMgmt;
    UCHAR Reserved[2];
//ULONG CheckEnd;
} WCB, *PWCB;

typedef struct _SDIO_TX_PKT_T
{
    WCB         Wcb;
    UCHAR       Pkt[SDIO_MAX_PKT_LEN];
} SDIO_TX_PKT_T, *PSDIO_TX_PKT_T;

#define TxSmallPktSize          300         /*< If the Tx packet size is less than this one, it could be a control packet => Don't aggregate the later ones in this node*/
#define TxPKTAggreCnt           3
//#define FM_TX_PKT_GAP_LEN		16u     /*< The gap between each packets*/
#define FM_TX_PKT_GAP_LEN		28u     /*< The gap between each packets*/
#define TX_COMMBUF_SIZE			(TxPKTAggreCnt * (sizeof(SDIO_TX_PKT_T)+FM_TX_PKT_GAP_LEN))
typedef struct _TX_MPKT_T
{
    UCHAR       Pkt[TX_COMMBUF_SIZE];
} TX_MPKT_T, *PTX_MPKT_T;

typedef struct _SDIO_TX_PKT
{
    // lenth of the sdio communication packet
    USHORT  Len;

    // type of the sdio communication packet
    USHORT  Type;

    union 
    {
        TX_MPKT_T      TxDataBuf;
        UCHAR          CmdBuf[SDIO_MAX_CMD_LEN];
    } Buf;
} SDIO_TX_PKT, *PSDIO_TX_PKT;
#pragma pack()

typedef USHORT  TXMASKID;
typedef WCHAR	TRNREASON[48];
typedef NDIS_STATUS		(*PKTFILTERFUNC)		(PVOID	pParam, PSDIO_TX_PKT pDnldPacket);
typedef struct _ExecCmd 
{
	PKTFILTERFUNC	ExecFunc;
	PVOID		FuncArg;
} EXECCMD, *PEXECCMD;
typedef struct _ExecCmdNode
{
	EXECCMD		func;
	struct _ExecCmdNode* pNext;
} EXECCMDNODE, *PEXECCMDNODE;

typedef enum {
	TX_IDLE,		///External is available to send the packets
	TX_SENDING,		///Packet has been sending. (Data has been downloaded, but Tx-Done has not come back)
	TX_STATE_MAX	///Maximum Tx-State
} TX_STATE;

typedef struct {
	TX_STATE	state;
    ULONG       TxPendCnt;
} TR_TX_STATE, *PTR_TX_STATE;


/*
Data structure to initialize the TxParam
*/
typedef struct _tx_init
{
    USHORT          MaxTxAggrCnt;
	PMRVDRV_ADAPTER	pAdapter;
	NDIS_HANDLE		MrvDrvAdapterHdl;
} TXINIT, *PTXINIT;

typedef enum {
    TF_BEFORE,          ///Right before the data is being downloaded
    TF_AFTER,           ///Right after the data is being downloaded
    TD_BEFORE,          ///Right before getting tx-done
    TD_AFTER,           ///Right after getting tx-done
    TF_MAXIMUM
} TXFILTER_TYPE;
/* ========================================================================= */
///Init/Deinit interface
NDIS_STATUS InitTxParam(IN PPVOID, IN PTXINIT);
NDIS_STATUS	DeinitTxParam(IN PVOID);


///Sending packets
NDIS_STATUS CCX_SendSinglePacket(IN PVOID, IN PNDIS_PACKET); 
void SendOneQueuedPacket(IN PVOID);
NDIS_STATUS SendNullPacket(IN PVOID,UCHAR pwmgr );
NDIS_STATUS TxSend(IN PVOID, IN PNDIS_PACKET Packet, UINT Flag);
PNDIS_PACKET SetTxDone(IN PVOID);
///void ContinueTxProcess(IN PVOID ipTxParam);
void TxStartSend(PVOID	ipTxParam);

/// Miscellaneous functions
/// NDIS (tx filters) functions
NDIS_STATUS RegisterFilterFuncForTx(IN PVOID	ipTxParam, TXFILTER_TYPE TFType, PKTFILTERFUNC func, PVOID pFuncArg);
BOOLEAN TxCheckForHang(IN PVOID);
VOID SetTxAggrCnt(IN PVOID ipTxParam, USHORT AggrCnt);


//cleanup functions
void EmptyTxQueue(IN PVOID);
void EmptyTxPendingPkt(IN PVOID);
NDIS_STATUS CleanUpSingleTxBuffer(IN PVOID);


///Functions to get status 
ULONG GetTxCtrlValue(IN PVOID);
//    BOOLEAN	IsTxPktSending(IN PVOID );
///BOOLEAN	IsTxQueueEmpty(IN PVOID);
//    BOOLEAN	ReadyForNextTxPacket(IN PVOID	ipTxParam);
//    int GetTxPendingPktCnt(IN PVOID);
//    UINT GetTxPktLen(IN PVOID ipTxParam);

VOID GetTxStatus(IN PVOID ipTxParam, OUT PTR_TX_STATE pTxState);

#ifdef __cplusplus
}
#endif ///__cplusplus
#endif ///TXPROC_H

